#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/atomic.h>
#include <linux/printk.h>

#define NAME(k) "thread"#k
#define ID 231

MODULE_LICENSE("GPL");
MODULE_AUTHOR("LUO");
MODULE_DESCRIPTION("deferred work");
MODULE_VERSION("1.0");

/// @brief 存放work_struct与id信息
struct work_ctx
{
    struct work_struct work;
    int current_id;
};
struct delayed_work my_work;

struct work_ctx works[10];

struct task_struct *threads[10];

static int num[10];

static int work_count = 0;
static int thread_count = 0;

/// @brief kthread执行体
/// @param data 传入参数
/// @return
static int kthread_handler(void *data)
{
	//TODO Add Code here
    int *value = (int*)data;
    pr_info("kthread : %d", *value);
    // while (!kthread_should_stop()) {
    //     msleep_interruptible(2000);
    // }
    ++thread_count;
    return 0;
}
/// @brief work queue执行体
/// @param work
static void work_queue_handler(struct work_struct *work)
{
    struct work_ctx *ctx = container_of(work, struct work_ctx, work);

    printk("work queue : %d", ctx->current_id);
    ++work_count;
}
/// @brief delayed work执行体
/// @param work 
static void delayed_work_handler(struct work_struct *work)
{
    printk("delayed work!\n");
}

/// @brief 内核模块初始化
/// @param
/// @return
static int __init deferred_work_init(void)
{
    printk(KERN_INFO "deferred work module init\n");
    int i;
  	//TODO Add Code here,init workqueue and kernel thread
    // 初始化待打印的编号
    for (i = 0; i < 10; ++i) {
        num[i] = ID + i;
    }
    // 初始化工作
    for (i = 0; i < 10; ++i) {
        INIT_WORK(&works[i].work, work_queue_handler);
        works[i].current_id = num[i];
    }
    // 建立线程
    for (i = 0; i < 10; ++i) {
        threads[i] = kthread_create(kthread_handler, &num[i], NAME(i));
        if (IS_ERR(threads[i])) {
            pr_err("Failed to create %s, error code : %ld", NAME(i), PTR_ERR(threads[i]));
            return PTR_ERR(threads[i]);
        }
    }
    // 将工作加入工作队列
    // pr_info("scheduling normal work\n");
    for (int i = 0; i < 10; ++i) {
        schedule_work(&works[i].work);
    }
    // 等待所有工作完成
    while (work_count != 10) {
        msleep_interruptible(20);
    }
    // 唤醒每个进程
    // pr_info("wake kthread\n");
    for (int i = 0; i < 10; i++) {
        wake_up_process(threads[i]);
    }
    // 初始化延迟工作并加入工作队列
    INIT_DELAYED_WORK(&my_work, delayed_work_handler);
    schedule_delayed_work(&my_work, secs_to_jiffies(5));

    return 0;
}
/// @brief 内核模块退出
/// @param
static void __exit deferred_work_exit(void)
{
	//TODO Add Code here
    // 清理线程(等待所有内核线程结束)
    while (thread_count != 10) {
        set_current_state(TASK_INTERRUPTIBLE);
        schedule_timeout(msecs_to_jiffies(1000));
    }
    // 等待延迟化工作完成
    while (delayed_work_pending(&my_work)) {
        pr_info("waiting for delayed_work\n");
        msleep_interruptible(1000);
    }

    printk(KERN_INFO "deferred work module exit\n");
}

module_init(deferred_work_init);
module_exit(deferred_work_exit);
